/* eslint-disable no-unused-vars */
/*
 * @Author      : ZhouQiJun
 * @Date        : 2025-08-31 16:06:04
 * @LastEditors : ZhouQiJun
 * @LastEditTime: 2025-09-04 03:09:50
 * @Description : 要素绘制、修改接口
 */
import { type ProjCode } from '#ol-vue-hooks'
import type { Placement } from '@floating-ui/dom'
import type { Feature } from 'ol'

import type { StyleLike } from 'ol/style/Style'

/**
 * 定义合法的 DOM id 类型
 * - 以字母或下划线开头
 * - 后续字符可以是字母、数字、下划线 _ 或短横 -
 */
type Alpha =
  | 'a'
  | 'b'
  | 'c'
  | 'd'
  | 'e'
  | 'f'
  | 'g'
  | 'h'
  | 'i'
  | 'j'
  | 'k'
  | 'l'
  | 'm'
  | 'n'
  | 'o'
  | 'p'
  | 'q'
  | 'r'
  | 's'
  | 't'
  | 'u'
  | 'v'
  | 'w'
  | 'x'
  | 'y'
  | 'z'
  | 'A'
  | 'B'
  | 'C'
  | 'D'
  | 'E'
  | 'F'
  | 'G'
  | 'H'
  | 'I'
  | 'J'
  | 'K'
  | 'L'
  | 'M'
  | 'N'
  | 'O'
  | 'P'
  | 'Q'
  | 'R'
  | 'S'
  | 'T'
  | 'U'
  | 'V'
  | 'W'
  | 'X'
  | 'Y'
  | 'Z'
  | '_'

type Digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'

type IdChar = Alpha | Digit | '-' | '_'

/**
 * 递归模板字面量类型，表示合法 DOM id
 * 注意：TypeScript 不能无限递归，这只是形式检查
 */
export type DomId<S extends string = ''> = S extends `${infer First}${infer Rest}`
  ? First extends Alpha
    ? Rest extends ''
      ? S
      : `${First}${DomId<Rest>}`
    : never
  : never

export type GeoType =
  | 'Point'
  //| 'MultiPoint'
  | 'LineString'
  //| 'MultiLineString'
  | 'LinearRing'
  | 'Polygon'
  //| 'MultiPolygon'
  | 'Circle'
  | 'None'
//| 'GeometryCollection'

export type FeatureOptions = {
  /**
   * 数据的投影
   */
  dataProjection?: ProjCode
  /**
   * 要素的投影，和地图的投影相同
   */
  featureProjection?: ProjCode
  /**
   * 范围
   */
  extent?: number[]
  /**
   * 样式
   */
  style?: StyleLike
}

export type Id = string | number

export type Confirm = {
  cancel?: string
  ok?: string
  confirmContent?: string
  id?: string
  placement?: Placement
  trigger?: HTMLElement
}

export type ConfirmOptions = {
  trigger?: HTMLElement
  confirm?: Confirm | boolean
}
/**
 * @description: OpenLayers Draw Interaction Interface
 */
export abstract class OlDrawI {
  /**
   * 根据 wkt 添加要素
   * @param wkt wkt字符串
   * @param options 配置对象
   * @param id 可选的 id
   */
  abstract addFeature(wkt: string, options: FeatureOptions, id?: Id): boolean

  /**
   * 移除要素 成功移除后返回 true
   * @param id 要素id
   */
  abstract removeFeatures(id: Id | Id[]): boolean
  /**
   * 移除所有要素
   */
  abstract removeAllFeatures(options?: ConfirmOptions): Promise<boolean>
  /**
   * 启用绘制
   * @param type 几何类型
   * @param freehand 是否开启自由绘制
   */
  abstract enableDraw(type: GeoType, freehand?: boolean): void
  /**
   * 启用自由绘制
   * // NOTE 只有正在绘制【线】、【多边形】和【圆】才生效，才有意义
   * @returns 是否启用成功
   */
  abstract enableFreehand(): boolean
  /**
   * 禁用自由绘制
   * @returns 是否禁用成功
   */
  abstract disableFreehand(): boolean
  /**
   * 禁用绘制
   */
  abstract disableDraw(): void
  /**
   * 选中要素
   * @param idsOrFeatures 要素id 或者 要素组成的数组
   */
  abstract enableSelect(idsOrFeatures?: Id[] | Feature[]): void
  /**
   * 禁用选中的要素
   * @param idsOrFeatures 要素id 或者 要素组成的数组
   */
  abstract disableSelect(idsOrFeatures?: Id[] | Feature[]): void
  /**
   * 开启修改 启用后要素可修改，触发 'modifyenable' 事件
   * @param id 单个 id 或者 id 数组
   * @param style 启用修改后的样式
   */
  abstract enableModify(id?: Id | Id[], style?: StyleLike): void
  /**
   * 禁用修改，禁用后要素不可修改，触发 'modifydisable' 事件
   * // NOTE 修改期间修改要素，会触发 modifyend 和 modifystart
   * @param id 单个 id 或者 id 数组
   * @param style 禁用编辑后的样式，不提供，恢复到启用修改的样式
   */
  abstract disableModify(id?: Id | Id[], style?: StyleLike): void
  /**
   * 启用平移
   * @param id 要素 id
   */
  abstract enableTranslate(id?: Id): void
  /**
   * 禁用平移
   * @param id 要素 id
   */
  abstract disableTranslate(id?: Id): void
  /**
   * 完成绘制
   */
  abstract completeDraw(): void
}
